5.02. Работа с типами
Работа с типами
Преобразование типов
Преобразование типов — процесс изменения типа объекта путём интерпретации его значения в контексте другого типа. В Python различают явное (принудительное) и неявное (автоматическое) приведение типов. Явные преобразования осуществляются с помощью встроенных конструкторов типов.
Основные функции преобразования:
- int(x) — преобразует x в целое число. При преобразовании строки она должна содержать корректное целочисленное представление (возможно с знаком). При преобразовании числа с плавающей точкой отбрасывается дробная часть (усечение к нулю, а не округление). Примеры:
int("42") → 42,int(3.9) → 3. - float(x) — преобразует x в число с плавающей точкой. Поддерживает строки с десятичной записью, экспоненциальной формой ("1e3"), а также inf, nan. Примеры:
float("3.14") → 3.14,float(5) → 5.0. - str(x) — возвращает строковое представление объекта. Вызывает метод
__str__()объекта. Для встроенных типов результат обычно человеко-читаем. Пример:str(123) → "123",str(True) → "True". - bool(x) — возвращает True или False в соответствии с логическим значением объекта. Следует помнить, что в Python большинство объектов имеют «истинное» значение, за исключением None, False, 0, 0.0, 0j, пустых коллекций и строк (
"",[],{}), и объектов с переопределенным__bool__()или__len__(), возвращающим 0.boolне является просто «обёрткой» вокруг 0/1. Это полноценный тип, наследуемый от int, где True == 1, False == 0, но это не означает эквивалентности семантики.
Статическая типизация и аннотации
Несмотря на динамическую природу Python, в современной разработке активно применяются инструменты статической типизации. Они позволяют выявлять ошибки на этапе анализа кода, улучшать автодополнение в IDE и документировать сигнатуры функций.
Статическая типизация реализуется через аннотации типов (PEP 484) и сторонние анализаторы.
Аннотации типов добавляются с помощью синтаксиса:
def process_data(value: str) -> int:
return len(value)
Они не влияют на выполнение программы, но доступны через __annotations__ и используются анализаторами.
Инструменты статического анализа:
- mypy — один из первых и наиболее распространённых статических анализаторов. Проверяет соответствие аннотаций типов, включая сложные случаи: объединения (Union), опциональные типы (Optional), дженерики.
- pyright — анализатор от Microsoft, написанный на TypeScript, интегрирован в VS Code. Отличается высокой скоростью и хорошей поддержкой современных возможностей Python (например, LiteralString, TypeGuard).
- pyre — разработан Facebook (Meta), ориентирован на производительность при анализе больших проектов. Менее популярен, но эффективен в специфических средах.
- Pydantic — не является анализатором типов, но активно использует аннотации для валидации данных при создании моделей. Обеспечивает runtime-проверку типов на основе схем, что делает его мощным инструментом для API и конфигураций.
Cтатическая типизация в Python — опциональна и не заменяет тестирование. Она снижает вероятность определённых классов ошибок, но не гарантирует корректность логики.
Работа с числами
Числовые типы в Python включают int, float, complex и decimal.Decimal (из стандартного модуля decimal). Рассмотрим основные операции и особенности.
Арифметические операции
Арифметические операции:
+,-,*,/— обычное деление (всегда возвращает float)//— целочисленное деление (floor division)%— остаток от деления**— возведение в степень-x,+x— унарные операции
Из особенностей, можно отметить следующее -
- деление
/всегда возвращаетfloat, даже если операнды делятся нацело; - целочисленное деление
//округляет вниз (к меньшему целому), включая отрицательные числа:-7 // 2 = -4; - приоритет операций следует математическим правилам; для группировки используются скобки.
Модуль math
В стандартной библиотеке имеется модуль math, который можно добавить командой import math и использовать расширенные математические операции.
import math
print(math.pi) # 3.1415...
print(math.sqrt(25)) # 5.0
Округление
Python предоставляет несколько способов округления:
- round(x) — стандартное округление к ближайшему чётному при равенстве расстояний (банковское округление). Пример: round(2.5) → 2, round(3.5) → 4.
- math.floor(x) — округление вниз.
- math.ceil(x) — округление вверх.
- math.trunc(x) — усечение дробной части (эквивалентно int(x) для положительных).
Модуль decimal
Для задач, требующих точной арифметики (финансовые расчёты, измерения), рекомендуется использовать тип Decimal из модуля decimal. Он представляет числа в виде десятичных дробей, избегая ошибок двоичного округления (0.1 + 0.2 != 0.3 в float). Точность и режим округления настраиваются через контекст (getcontext()). Операции выполняются медленнее, чем с float, но обеспечивают предсказуемость.
from decimal import Decimal, getcontext
getcontext().prec = 6
result = Decimal('0.1') + Decimal('0.2') # → Decimal('0.3')
Не следует сравнивать float на равенство. Вместо этого используйте math.isclose().
Работа со строками
Строки в Python — неизменяемые последовательности Unicode-символов (тип str). Поддерживают широкий набор операций и методов.
Конкатенация и повторение
Конкатенация: s1 + s2, через оператор «+».
Повторение: s * n (где n — целое).
Не рекомендуется использовать + в цикле для сборки строк — из-за неизменяемости каждый раз создаётся новый объект. Вместо этого следует использовать ''.join(iterable).
Пример конкатенации:
s1 = "Текст"
s2 = " и ещё текст."
print(s1 + s2)
Результат: Текст и ещё текст.
first = "Привет"
second = "мир"
result = first + " " + second + "!"
print(result) # Привет мир!
Пример повторения:
s = "Текст"
print(s * 3)
Результат будет «ТекстТекстТекст».
laugh = "ха"
print(laugh * 5) # хахахахаха
line = "-=" * 10
print(line) # -=-=-=-=-==-=-=-=-=-=-
Форматирование строк
Существует несколько подходов:
f-строки (PEP 498)
name = "Alice"
print(f"Hello, {name}!")
F-строка означает «formatted string». Синтаксис подразумевает добавление буквы f перед текстом. Он позволяет подставлять переменные через фигурные скобки - {имя_переменной}.
Поддерживают выражения, вызовы функций, форматирование (:.2f, !r и т.д.).
name = input("Введите имя: ")
print(f"Твоё имя: {name}")
print(f"Первая буква: {name[0]}")
print(f"Последняя буква: {name[-1]}")
print(f"Длина имени: {len(name)} букв")
print(f"Имя заглавными: {name.upper()}")
Метод .format()
"Hello, {}!".format(name)
"Value: {value:.2f}".format(value=3.1415)
Здесь принцип похож на f-строки, но подразумевает более неудобный синтаксис - нужно расставить в текст фигурные скобки {}, а уже после текста добавить вызов метода format() и в параметрах передать переменную или значение переменной.
% formatting
"Hello, %s!" % name
% подразумевает подстановку значения с использованием особого форматирования:
- '%d', '%i', '%u' - десятичное число;
- '%o' - число в восьмеричной системе счисления;
- '%x' - число в шестнадцатеричной системе счисления (буквы в нижнем регистре);
- '%X' - число в шестнадцатеричной системе счисления (буквы в верхнем регистре);
- '%e' - число с плавающей точкой с экспонентой (экспонента в нижнем регистре);
- '%E' - число с плавающей точкой с экспонентой (экспонента в верхнем регистре);
- '%f', '%F' - число с плавающей точкой (обычный формат);
- '%g' - число с плавающей точкой. с экспонентой (экспонента в нижнем регистре), если она меньше, чем -4 или точности, иначе обычный формат;
- '%G' - число с плавающей точкой. с экспонентой (экспонента в верхнем регистре), если она меньше, чем -4 или точности, иначе обычный формат;
- '%c' - символ (строка из одного символа или число - код символа);
- '%s' - строка;
- '%%' - знак «%».
Учитывая «замудрённость» подходов, очевидно, что лучше использовать первый метод, f-строки.
Срезы (slicing) и доступ по индексу
Слово "PYTHON" — это 6 ячеек:
Буква
P - 0
Y - 1
T - 2
H - 3
O - 4
N - 5
Доступ к символам: [0], [1], [-1]
word = "Привет"
print(word[0]) # П — первая буква
print(word[1]) # р
print(word[5]) # т — шестая буква
print(word[-1]) # т — последняя (отсчёт с конца!)
print(word[-2]) # е — предпоследняя
Строки поддерживают доступ по индексу и срезы:
s[i]— символ по индексу (от 0 до len(s)-1, отрицательные индексы отсчитываются с конца).s[start:stop:step]— срез.
Примеры:
s[1:4]— символы с 1 по 3.s[::-1]— строка в обратном порядке.s[::2]— каждый второй символ.
s = "Текст"
print(s[1:4])
Результат будет «екс».
Срезы безопасны: выход за границы не вызывает исключения, возвращается пустая строка или максимально возможный фрагмент.
Методы для работы со строками
Основные методы строк:
s.upper(),s.lower()— изменение регистра.s.strip([chars])— удаление пробельных символов (или указанных) с концов.s.split(sep=None)— разбиение на список по разделителю.s.replace(old, new[, count])— замена подстроки.s.startswith(prefix),s.endswith(suffix)— проверка начала/конца.s.find(sub)— возвращает индекс первого вхождения или -1.s.index(sub)— аналогично find, но вызывает ValueError при отсутствии.s.isalpha(),s.isdigit(),s.isalnum()— проверка содержимого.
# .upper()
# ВСЁ ЗАГЛАВНЫМИ
"привет".upper()→"ПРИВЕТ"
# .lower()
# всё маленькими
"ПРИВЕТ".lower()→"привет"
# .title()
# Каждое Слово С Заглавной
"привет мир".title()→"Привет Мир"
Все методы возвращают новую строку, так как строки неизменяемы.
Работа с булевыми значениями
Тип bool — подкласс int, содержащий два значения: True и False. Используется для логических выражений, условий и управления потоком выполнения.
Логические операторы
Логические операторы
and— логическое И (возвращает последнее истинное или первое ложное значение).or— логическое ИЛИ (возвращает первое истинное или последнее ложное).not— логическое НЕ (возвращает True или False).
Операторы поддерживают ленивую (short-circuit) семантику: второе выражение вычисляется только при необходимости.
x = a and b # если a — False, b не вычисляется
Сравнения
Операторы сравнения (==, !=, <, <=, >, >=) возвращают bool.
==проверяет равенство значений, is — идентичность объектов.- Сравнение разных типов возможно, но может давать неочевидные результаты (например,
1 == True— True, так как bool — подкласс int). - Избегайте сравнения float на равенство; используйте math.isclose().
Любой объект может быть интерпретирован в булевом контексте (в if, while, and/or). Пустые или нулевые значения считаются ложными, остальные — истинными.
Работа с датами и временем
Модуль datetime предоставляет средства для работы с датами, временем и интервалами. Основные типы:
datetime.datetime— комбинированный объект дата+время.datetime.date— только дата.datetime.time— только время.datetime.timedelta— разница между двумя моментами времени.datetime.timezone— информация о часовом поясе.
Создание объектов
from datetime import datetime, date, timezone
now = datetime.now() # текущие дата и время
utc_now = datetime.now(timezone.utc)
specific = datetime(2025, 4, 5, 12, 30, 0)
today = date.today()
Форматирование
Форматирование и парсинг:
strftime(format)— форматирование в строку.strptime(string, format)— парсинг строки в объект.
dt = datetime(2025, 4, 5)
dt.strftime("%Y-%m-%d") # → "2025-04-05"
datetime.strptime("2025-04-05", "%Y-%m-%d")
strptime чувствителен к формату и выбрасывает ValueError при несоответствии.
Работа с временем
Операции с временем:
timedelta позволяет прибавлять/вычитать интервалы:
from datetime import timedelta
tomorrow = now + timedelta(days=1)
Разницу между двумя datetime можно получить как timedelta.
Рекомендуется работать с UTC внутри системы и конвертировать в локальное время только на вывод. timezone.utc — константа для UTC.
Для сложных сценариев (летнее время, правила перехода) используется сторонняя библиотека pytz или встроенный zoneinfo (начиная с Python 3.9).